home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / iguana / incosrc / incosrc.exe / UTIL / DGIF.ARJ / DGIF.C next >
C/C++ Source or Header  |  1994-02-13  |  8KB  |  325 lines

  1. /* ------------------------------- DGIF.C -------------------------------- */
  2. /* DGIF, GIF dumper bye Jare using Mark Morley's fab VGL.
  3.  * Bugfixed version, now displays correctly GIFs of width < 320.
  4.  * Also fully translated to english. O:-)
  5.  * I haven't tried with GIFs bigger than 64Kb.
  6.  */
  7.  
  8. /******************************************************************************
  9.  VGLGIF.C
  10.  
  11.  VGLGif( char* file, char far* buffer, char far* palette,
  12.          int* width, int* height );
  13.  
  14.  Routine to load a 256 color .GIF file into a memory buffer.  *Only* 256
  15.  color images are supported here!  Sorry, no routines to SAVE .GIFs...
  16.  Memory required is allocated on the fly and no checks are in place.  If you
  17.  don't have enough memory it will likely crash.  It's easy to add the checks
  18.  yourself, just put one after each call to malloc().  If you supply a pointer
  19.  to a palette, it will be filled in.  If you supply a pointer to a width
  20.  and/or height variable, it will be filled in as well.
  21.  
  22.  This code is hereby placed in the public domain.  Have fun!
  23.  
  24.  Mark Morley
  25.  morley@camosun.bc.ca
  26.  ******************************************************************************/
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <alloc.h>
  31. #include <string.h>
  32. #include <dos.h>
  33.  
  34. #define MAX_CODES     4096
  35.  
  36. static FILE*          fp;
  37. static int            curr_size;
  38. static int            clear;
  39. static int            ending;
  40. static int            newcodes;
  41. static int            top_slot;
  42. static int            slot;
  43. static int            navail_bytes = 0;
  44. static int            nbits_left = 0;
  45. static unsigned char  b1;
  46. static unsigned char  byte_buff[257];
  47. static unsigned char* pbytes;
  48. static unsigned char* stack;
  49. static unsigned char* suffix;
  50. static unsigned int*  prefix;
  51.  
  52. static unsigned long code_mask[13] =
  53. {
  54.    0L,
  55.    0x0001L, 0x0003L,
  56.    0x0007L, 0x000FL,
  57.    0x001FL, 0x003FL,
  58.    0x007FL, 0x00FFL,
  59.    0x01FFL, 0x03FFL,
  60.    0x07FFL, 0x0FFFL
  61. };
  62.  
  63. static int pascal
  64. get_next_code(void)
  65. {
  66.    register int  i;
  67.    static unsigned long ret;
  68.  
  69.    if( ! nbits_left )
  70.    {
  71.       if( navail_bytes <= 0 )
  72.       {
  73.      pbytes = byte_buff;
  74.          navail_bytes = getc( fp );
  75.      if( navail_bytes )
  76.         for( i = 0; i < navail_bytes; ++i )
  77.                *(byte_buff + i) = getc( fp );
  78.       }
  79.       b1 = *pbytes++;
  80.       nbits_left = 8;
  81.       --navail_bytes;
  82.    }
  83.    ret = b1 >> (8 - nbits_left);
  84.    while( curr_size > nbits_left )
  85.    {
  86.       if( navail_bytes <= 0 )
  87.       {
  88.      pbytes = byte_buff;
  89.          navail_bytes = getc( fp );
  90.      if( navail_bytes )
  91.         for( i = 0; i < navail_bytes; ++i )
  92.                *(byte_buff + i) = getc( fp );
  93.       }
  94.       b1 = *pbytes++;
  95.       ret |= b1 << nbits_left;
  96.       nbits_left += 8;
  97.       --navail_bytes;
  98.    }
  99.    nbits_left -= curr_size;
  100.  
  101.    return( (int) (ret & *(code_mask + curr_size)) );
  102. }
  103.  
  104. int VGLGif( char* file, char far* buffer, char far* pal, int* width, int* height )
  105. {
  106.    unsigned char* sp;
  107.    int            code, fc, oc;
  108.    int            i;
  109.    unsigned char  size;
  110.    int            c;
  111.    unsigned char  buf[1028];
  112.    unsigned char  red;
  113.    unsigned char  grn;
  114.    unsigned char  blu;
  115.  
  116.    fp = fopen( file, "rb" );
  117.    if( !fp )
  118.       return( 0 );
  119.    fread( buf, 1, 6, fp );
  120.    if( strncmp( (char *)buf, "GIF", 3 ) )
  121.    {
  122.       fclose( fp );
  123.       return( 0 );
  124.    }
  125.    fread( buf, 1, 7, fp );
  126.    for( i = 0; i < 768; )
  127.    {
  128.       red = getc( fp );
  129.       grn = getc( fp );
  130.       blu = getc( fp );
  131.  
  132.       if( pal )
  133.       {
  134.          pal[i++] = red >> 2;
  135.          pal[i++] = grn >> 2;
  136.          pal[i++] = blu >> 2;
  137.       }
  138.       else
  139.          i += 3;
  140.    }
  141.    fread( buf, 1, 5, fp );
  142.    i = getw( fp );
  143.    if( width )
  144.       *width = i;
  145.    i = getw( fp );
  146.    if( height )
  147.       *height = i;
  148.    if( !buffer ) {
  149.       fclose(fp);
  150.       return( 1 );
  151.    }
  152.    fread( buf, 1, 1, fp );
  153.    size = getc( fp );
  154.    if( size < 2 || 9 < size )
  155.    {
  156.       fclose( fp );
  157.       return( 0 );
  158.    }
  159.  
  160.    stack = (unsigned char*) malloc( MAX_CODES + 1 );
  161.    suffix = (unsigned char*) malloc( MAX_CODES + 1 );
  162.    prefix = (unsigned int*) malloc( sizeof(int) * (MAX_CODES + 1) );
  163.  
  164.    curr_size = size + 1;
  165.    top_slot = 1 << curr_size;
  166.    clear = 1 << size;
  167.    ending = clear + 1;
  168.    slot = newcodes = ending + 1;
  169.    navail_bytes = nbits_left = 0;
  170.    oc = fc = 0;
  171.    sp = stack;
  172.    while( (c = get_next_code()) != ending )
  173.    {
  174.       if( c == clear )
  175.       {
  176.      curr_size = size + 1;
  177.      slot = newcodes;
  178.      top_slot = 1 << curr_size;
  179.      while( (c = get_next_code()) == clear );
  180.      if( c == ending )
  181.         break;
  182.      if( c >= slot )
  183.         c = 0;
  184.      oc = fc = c;
  185.          *buffer++ = c;
  186.       }
  187.       else
  188.       {
  189.      code = c;
  190.      if( code >= slot )
  191.      {
  192.         code = oc;
  193.         *sp++ = fc;
  194.      }
  195.      while( code >= newcodes )
  196.      {
  197.         *sp++ = *(suffix + code);
  198.         code = *(prefix + code);
  199.      }
  200.      *sp++ = code;
  201.      if( slot < top_slot )
  202.      {
  203.         *(suffix + slot) = fc = code;
  204.         *(prefix + slot++) = oc;
  205.         oc = c;
  206.      }
  207.      if( slot >= top_slot && curr_size < 12 )
  208.      {
  209.         top_slot <<= 1;
  210.         ++curr_size;
  211.      }
  212.      while( sp > stack )
  213.      {
  214.         --sp;
  215.             *buffer++ = *sp;
  216.      }
  217.       }
  218.    }
  219.    free( stack );
  220.    free( suffix );
  221.    free( prefix );
  222.    fclose( fp );
  223.    return( 1 );
  224. }
  225.  
  226.  
  227. // =======================================================
  228.  
  229. void Error(const char *txt) {
  230.    printf("ORROR: %s\n", txt);
  231.    exit(1);
  232. }
  233.  
  234. void Usage(void) {
  235.    puts("DGIF, GIF dumper bye Jare using Mark Morley's fab VGL.\n"
  236.         "   Usage: DGIF file[.GIF]");
  237.    exit(1);
  238. }
  239.  
  240.  
  241. void DumpFile(const char* fn, char huge* buf, unsigned long l) {
  242.    FILE *f;
  243.  
  244.    printf("Writing %ld bytes from %lX to file  %s\n", l, (long)buf, fn);
  245.    if ((f = fopen(fn, "wb")) == NULL)
  246.       Error("Creating file.");
  247.    while (l > 16384L) {
  248.       if (fwrite(buf, 16384, 1, f) < 1)
  249.           Error("Writing file");
  250.       buf = buf + 16384;
  251.       l -= 16384;
  252.       printf("Still %ld bytes left at %lX.\n", l, (long)buf);
  253.    }
  254.    if (fwrite(buf, (unsigned)l, 1, f) < 1)
  255.       Error("Finishing with file");
  256.    fclose(f);
  257. }
  258.  
  259. char fname[200];
  260. char pal[768];
  261.  
  262. void main(int argc, char *argv[]) {
  263.    char *p, *g;
  264.    int   w = -1, h = -1;
  265.    int   i;
  266.    int   ok;
  267.  
  268.    char far* im;
  269.  
  270.    if (argc < 2)
  271.       Usage();
  272.    p = strrchr(argv[1], '.');
  273.    g = strrchr(argv[1], '\\');
  274.    if (p && (!g || g < p))
  275.       *p = '\0';
  276.    sprintf(fname, "%s.GIF", argv[1]);
  277.  
  278.    printf("Leyendo %s...\n", fname);
  279.    ok = VGLGif(fname, NULL, NULL, &w, &h);
  280.    if (!ok)
  281.       Error("Fichero no encontrado");
  282.    printf("X = %d, Y = %d\n", w, h);
  283.  
  284.    printf("Memory left: %ld\n", farcoreleft());
  285.    if ( (im = farmalloc((unsigned)w*h)) == NULL)
  286.       Error("Out of memory for image.");
  287.    printf("Memory left: %ld\n", farcoreleft());
  288.    ok = VGLGif(fname, im, pal, NULL, NULL);
  289.    if (!ok)
  290.       Error("Reloading gif.");
  291.  
  292.    asm {
  293.       PUSH SI
  294.       MOV AX,0x13
  295.       INT 0x10
  296.       MOV SI,OFFSET pal
  297.       MOV CX,768
  298.       MOV DX,0x3c8
  299.       XOR AL,AL
  300.       OUT DX,AL
  301.       INC DX
  302.       REP OUTSB
  303.    }
  304.  
  305.    for (i = 0; i < h; i++)
  306.        movedata(FP_SEG(im+i*w), FP_OFF(im+i*w), 0xA000, 320*i, w);
  307.  
  308.    asm {
  309.       MOV AH,0
  310.       INT 0x16
  311.       MOV AX,3
  312.       INT 0x10
  313.    }
  314.  
  315.  
  316.    printf("Memory left: %ld\n", farcoreleft());
  317.    sprintf(fname, "%s.pal", argv[1]);
  318.    DumpFile(fname, pal, 768);
  319.    sprintf(fname, "%s.pix", argv[1]);
  320.    DumpFile(fname, im, (unsigned)w*h);
  321.    exit(0);
  322. }
  323.  
  324. /* ---------------------------- End of DGIF.C ---------------------------- */
  325.